#pragma once
#include <iostream>
#include <memory>
#include <functional>

namespace cr_unique
{
    template <class T>
    struct defaultdel
    {
        void operator()(T *ptr)
        {
            delete ptr;
            ptr = nullptr;
        }
    };

    template <class T, class Del = defaultdel<T>>
    class unique_ptr
    {
    private:
        T *ptr;
        Del del;

    public:
        unique_ptr(T *p = nullptr)
            : ptr(p) { std::cout << "unique_ptr(T *p)" << std::endl; }

        // 禁掉拷贝构造和赋值
        unique_ptr(unique_ptr &p) = delete;
        unique_ptr &operator=(unique_ptr &p) = delete;

        unique_ptr(unique_ptr &&p)
        {
            std::cout << "std::unique_ptr(unique_ptr &&p)" << std::endl;
            ptr = p.ptr; // 内置类型
            p.ptr = nullptr;
        }
        // unique_ptr(std::unique_ptr<T> &&p)
        // {
        //     std::cout<<"unique_ptr(std::unique_ptr<T> &&p)"<<std::endl;
        //     ptr=p.get();
        //     p.release();
        // }
        unique_ptr &operator=(unique_ptr &&p)
        {
            std::cout << "unique_ptr &operator=(unique_ptr &&p)" << std::endl;
            del(ptr);
            ptr = p.ptr;
            p.ptr = nullptr;
            return *this;
        }
        T *operator->()
        {
            return ptr;
        }
        T &operator*()
        {
            return *ptr;
        }
        ~unique_ptr()
        {
            if (ptr)
            {
                del(ptr);
                ptr = nullptr;
            }
        }
    };
}